package com.heima.media.service.impl;

import com.alibaba.druid.sql.visitor.functions.If;
import com.alibaba.fastjson.JSON;
import com.heima.article.dto.ArticleDto;
import com.heima.article.fegin.ArticalFegin;
import com.heima.common.aliyun.service.AliyunGreenService;
import com.heima.common.dto.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.enums.MediaEnum;
import com.heima.common.minio.service.MinIOService;
import com.heima.media.dto.ContentDto;
import com.heima.media.entity.WmChannel;
import com.heima.media.entity.WmNews;
import com.heima.media.entity.WmUser;
import com.heima.media.service.IAuditService;
import com.heima.media.service.IWmChannelService;
import com.heima.media.service.IWmNewsService;
import com.heima.media.service.IWmUserService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import static com.heima.common.enums.MediaEnum.*;

/**
 * @Author xingsong
 * @Date 2022/7/31 20:45
 * @PackageName: com.heima.media.service.impl
 * @ClassName: AuditServiceImpl
 * @Description: TOOD
 * @Version 1.0
 */
@Service
public class AuditServiceImpl implements IAuditService {

    @Autowired
    private IWmNewsService wmNewsService;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService wmChannelService;
    @Autowired
    private ArticalFegin articalFegin;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private AliyunGreenService aliyunGreenService;

    /**
     * 该方法被自媒体人发布自媒体文章；网络爬虫爬取到文章后进行审核；人工审核
     * 自媒体文章审核
     *
     * @param wmNews
     */
    @Async("leadnewsExecutor")
    @Override
    public void audit(WmNews wmNews) {
        Integer status = wmNews.getStatus();
        if (status.equals(NEWS_SUBMIT_STATUS_PUBLISH.getVal())) {
            return;
        }
        if (status.equals(NEWS_SUBMIT_STATUS_ARTIFICIAL_PASS.getVal()) || status.equals(NEWS_SUBMIT_STATUS_PASS.getVal())) {
            if (System.currentTimeMillis() >= wmNews.getPublishTime().getTime()) {
                createArticleRemoteSave(wmNews);
            }
        }
        if (status.equals(NEWS_SUBMIT_STATUS_COMMIT.getVal())) {
            Map<String, Object> map = getTextAndImageFromContent(wmNews.getContent());
            String contentText = map.get("text").toString();
            List<String> contentImages = (List<String>) map.get("images");
            String allText = contentText + wmNews.getTitle();
            boolean flag = checkText(allText, wmNews);
            if (!flag) {
                return;
            }
            List<String> allImages = new ArrayList<>();
            if (!CollectionUtils.isEmpty(contentImages)) {
                allImages.addAll(contentImages);
            }
            String images = wmNews.getImages();
            if (StringUtils.isNotBlank(images)) {
                String[] split = images.split(",");
                List<String> strings = Arrays.asList(split);
                allImages.addAll(strings);
            }
            flag = checkImage(allImages, wmNews);
            if (!flag) {
                return;
            }
            if (System.currentTimeMillis() >= wmNews.getPublishTime().getTime()) {
                createArticleRemoteSave(wmNews);
            } else {
                wmNews.setStatus(NEWS_SUBMIT_STATUS_PASS.getVal());
                wmNewsService.updateById(wmNews);
            }
        }
    }

    /**
     * 构建发布文章对象，远程调用文章微服务保存发布文章
     *
     * @param wmNews 自媒体文章
     */
    private void createArticleRemoteSave(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);
        Integer userId = wmNews.getUserId();
        WmUser wmUser = wmUserService.getById(userId);
        if (wmUser != null) {
            articleDto.setAuthorId(wmUser.getApAuthorId());
            articleDto.setAuthorName(wmUser.getName());
        }
        WmChannel wmChannel = wmChannelService.getById(wmNews);
        if (wmChannel != null) {
            articleDto.setChannelName(wmChannel.getName());
        }
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag(ARTICLE_FLAG_NORMAL.getVal());
        ResponseResult<Long> responseResult = articalFegin.saveArticle(articleDto);
        if (responseResult.getCode().equals(AppHttpCodeEnum.SUCCESS.getCode())) {
            Long articleId = responseResult.getData();
            wmNews.setArticleId(articleId);
            wmNews.setStatus(NEWS_SUBMIT_STATUS_PUBLISH.getVal());
            wmNewsService.updateById(wmNews);
        }
    }

    /**
     * 直接拷贝 从正文中获取图片 文本
     *
     * @param content
     * @return
     */
    private Map<String, Object> getTextAndImageFromContent(String content) {
        StringBuilder stringBuilder = new StringBuilder();
        List<String> images = new ArrayList<>();
        HashMap<String, Object> mapResult = new HashMap<>();
        List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);
        for (ContentDto dto : contentDtos) {
            if ("text".equals(dto.getType())) {
                stringBuilder.append(dto.getValue());
            } else {
                images.add(dto.getValue());
            }
        }
        mapResult.put("text", stringBuilder.toString());
        mapResult.put("images", images);
        return mapResult;
    }

    /**
     * 阿里云文本审核，更新自媒体文章状态
     *
     * @param text   文章文本
     * @param wmNews 自媒体文章对象
     * @return
     */
    private boolean checkText(String text, WmNews wmNews) {
        boolean result = false;
        try {
            Map map = aliyunGreenService.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
            // 判断结果
            switch (suggestion) {
                case "pass":
                    // 审核通过
                    result = true;
                    break;
                case "block":
                    // 审核不通过
                    wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_FAIL.getVal());
                    // 获取不通过的原因
                    String label = (String) map.get("label");
                    wmNews.setReason("阿里云文本审核不通过: " + label);
                    wmNewsService.updateById(wmNews);
                    break;
                case "review":
                    // 人工审核
                    wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_ARTIFICIAL.getVal());
                    wmNewsService.updateById(wmNews);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("审核内容失败");
        }
        return result;
    }


    /**
     * 直接拷贝:阿里云图片审核:审核自媒体文章对象中：封面，正文中图片,更新自媒体文章状态
     *
     * @param images 封面+正文中图片
     * @param wmNews 自媒体文章对象
     * @return
     */
    private boolean checkImage(List<String> images, WmNews wmNews) {
        boolean result = false;
        if (images.size() <= 0) {
            return true;
        }
        try {
            List<byte[]> imagesList = new ArrayList<>();
            for (String url : images) {
                InputStream inputStream = minIOService.download(url);
                byte[] bytes = IOUtils.toByteArray(inputStream);
                imagesList.add(bytes);
            }
            Map map = aliyunGreenService.imageScan(imagesList);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion){
                case "pass":
                    result = true;
                    break;
                case "block":
                    wmNews.setStatus(NEWS_SUBMIT_STATUS_FAIL.getVal());
                    String label = (String) map.get("label");
                    wmNews.setReason("阿里云图片审核不通过:"+label);
                    wmNewsService.updateById(wmNews);
                    break;
                case "review":
                    // 人工审核
                    wmNews.setStatus(MediaEnum.NEWS_SUBMIT_STATUS_ARTIFICIAL.getVal());
                    wmNewsService.updateById(wmNews);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("审核图片失败");
        }
        return result;
    }
}
